#include "stdafx.h"
#include "CppUnitTest.h"
#include "..\src\type_traits.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace STL_Impl_UnitTest
{
TEST_CLASS(traits_unittest)
{
public:
		
TEST_METHOD(unittest_integral_constant)
{
    typedef stl::integral_constant<bool, true> true_type;
    Assert::AreEqual(true_type::value, true);

    typedef stl::integral_constant<int, 20> int_20;
    Assert::AreEqual(int_20::value, 20);
}

TEST_METHOD(unittest_true_type)
{
    Assert::AreEqual(stl::true_type::value, true);
}

TEST_METHOD(unittest_false_type)
{
    Assert::AreEqual(stl::false_type::value, false);
}

TEST_METHOD(unittest_enable_if)
{
    stl::enable_if<true, int>::type integral = 1;
    //stl::enable_if<false, int>::type integral;
}

TEST_METHOD(unittest_conditional)
{
    stl::conditional<true, bool, int>::type bool_value = true;
    
    stl::conditional<false, bool, int>::type int_value = 1;
}

TEST_METHOD(unittest_is_void)
{
    Assert::AreEqual(stl::is_void<void>::value, true);
    Assert::AreEqual(stl::is_void<int>::value, false);
}

TEST_METHOD(unittest_is_integral)
{
    Assert::AreEqual(stl::is_integral<int>::value, true);
    Assert::AreEqual(stl::is_integral<short>::value, true);
    Assert::AreEqual(stl::is_integral<long>::value, true);
    Assert::AreEqual(stl::is_integral<long long>::value, true);
    Assert::AreEqual(stl::is_integral<unsigned int>::value, true);
    Assert::AreEqual(stl::is_integral<unsigned short>::value, true);
    Assert::AreEqual(stl::is_integral<unsigned long>::value, true);
    Assert::AreEqual(stl::is_integral<unsigned long long>::value, true);
    Assert::AreEqual(stl::is_integral<char>::value, true);
    Assert::AreEqual(stl::is_integral<wchar_t>::value, true);
    Assert::AreEqual(stl::is_integral<signed char>::value, true);
    Assert::AreEqual(stl::is_integral<unsigned char>::value, true);
    Assert::AreEqual(stl::is_integral<bool>::value, true);

    Assert::AreEqual(stl::is_integral<double>::value, false);
}

TEST_METHOD(unittest_is_floating_point)
{
    Assert::AreEqual(stl::is_floating_point<float>::value, true);
    Assert::AreEqual(stl::is_floating_point<double>::value, true);
    Assert::AreEqual(stl::is_floating_point<long double>::value, true);

    Assert::AreEqual(stl::is_floating_point<bool>::value, false);
}

TEST_METHOD(unittest_is_array)
{
    Assert::AreEqual(stl::is_array<float[]>::value, true);
    Assert::AreEqual(stl::is_array<long[30]>::value, true);

    Assert::AreEqual(stl::is_array<bool>::value, false);
}

TEST_METHOD(unittest_is_pointer)
{
    Assert::AreEqual(stl::is_pointer<int*>::value, true);
    Assert::AreEqual(stl::is_pointer<const long*>::value, true);

    Assert::AreEqual(stl::is_pointer<bool>::value, false);
}

TEST_METHOD(unittest_is_lvalue_reference)
{
    Assert::AreEqual(stl::is_lvalue_reference<int&>::value, true);
    Assert::AreEqual(stl::is_lvalue_reference<const long&>::value, true);

    Assert::AreEqual(stl::is_lvalue_reference<bool&&>::value, false);
}

TEST_METHOD(unittest_is_rvalue_reference)
{
    Assert::AreEqual(stl::is_rvalue_reference<int&&>::value, true);
    Assert::AreEqual(stl::is_rvalue_reference<const long&&>::value, true);

    Assert::AreEqual(stl::is_rvalue_reference<bool&>::value, false);
}

TEST_METHOD(unittest_is_eference)
{
    Assert::AreEqual(stl::is_reference<int&>::value, true);
    Assert::AreEqual(stl::is_reference<int&&>::value, true);
    Assert::AreEqual(stl::is_reference<int>::value, false);
}

TEST_METHOD(unittest_is_arithmetic)
{
    Assert::AreEqual(stl::is_arithmetic<int>::value, true);
}

TEST_METHOD(unittest_is_function)
{
    //Assert::AreEqual(std::is_trivially_copyable<int(int)>::value, true);
}

};
}